package fr.neyb.wesb.core.data.descriptors.record;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import fr.neyb.framework.util.Tools;
import fr.neyb.wesb.core.data.content.Field;
import fr.neyb.wesb.core.data.content.Record;
import fr.neyb.wesb.core.data.descriptors.field.FieldDescriptor;
import fr.neyb.wesb.core.data.descriptors.record.RecordDescriptor;

public final class RecordDescriptor implements Iterable<FieldDescriptor> {

	private final List<FieldDescriptor> fieldDescriptors = new ArrayList<>();
	private final Map<String, Integer> nameMap;

	public RecordDescriptor(List<FieldDescriptor> fds, List<String> names) {
		Tools.checkNotNull(fds, names);
		if (fds.size() != names.size())
			throw new IllegalArgumentException(
					"fds et names ne sont pas de la meme taille");
		// TODO i18n
		this.fieldDescriptors.addAll(fds);
		nameMap = Tools.toMap(names);
	}

	@Override
	public int hashCode() {
		return fieldDescriptors.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!(obj instanceof RecordDescriptor))
			return false;
		RecordDescriptor rD = (RecordDescriptor) obj;
		return rD.fieldDescriptors.equals(fieldDescriptors);
	}

	public boolean validate(Record r) {
		List<Field> fields = r.getFields();
		if (fields.size() != fieldDescriptors.size())
			return false;

		Iterator<Field> fieldsIt = fields.iterator();
		for (FieldDescriptor fd : fieldDescriptors) {
			if (!fd.validateField(fieldsIt.next()))
				return false;
		}

		return true;
	}

//	@Override
//	public List<FieldDescriptor> getFieldDescr() {
//		return Collections.unmodifiableList(fieldDescriptors);
//	}

	public int size() {
		return fieldDescriptors.size();
	}

	/**
	 * prefer using indexes
	 */
	public FieldDescriptor get(String name) {
		Integer index = nameMap.get(name);
		return index == null ? null : fieldDescriptors.get(index);
	}

	public FieldDescriptor get(int index) {
		return fieldDescriptors.get(index);
	}

	public int getIndexOf(String name) {
		Integer index = nameMap.get(name);
		return index == null ? -1 : index;
	}

	public Iterator<FieldDescriptor> iterator() {
		return fieldDescriptors.iterator();
	}

	public boolean isAdmissible(Record r) {
		// TODO Auto-generated method stub
		return false;
	}

}
